package com.czx.drivingtest.service.impl;

import cn.miludeer.jsoncode.JsonCode;
import com.czx.drivingtest.dao.AuthDao;
import com.czx.drivingtest.dao.UserQuestionDao;
import com.czx.drivingtest.ex.LoginException;
import com.czx.drivingtest.model.entity.LocalAuth;
import com.czx.drivingtest.model.entity.TokenInfo;
import com.czx.drivingtest.model.entity.UserArchive;
import com.czx.drivingtest.service.AuthService;
import com.czx.drivingtest.utils.HttpClientUtils;
import com.czx.drivingtest.utils.IdWorker;
import com.czx.drivingtest.utils.JwtUtils;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author czx
 * @version 2020/6/10 11:43 下午
 * @since JDK12
 */
@Service
public class AuthServiceImpl implements AuthService {
    private static Logger logger = LoggerFactory.getLogger(AuthServiceImpl.class);

    @Autowired
    private AuthDao authDao;
    @Autowired
    private UserQuestionDao userQuestionDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TokenInfo login(String jsCode) {
        try {
            //用js_code去获取openid
            String openid = jsCode2Openid(jsCode);
            // 先判断系统中是否存在这个openid,如果存在,就查询出这个openid对应的用户信息,如果不存在,就添加一个新用户
            LocalAuth localAuth = authDao.queryLocalAuthByOpenid(openid);
            if (localAuth == null) {
                long userId = IdWorker.nextId();
                localAuth = new LocalAuth();
                localAuth.setUserId(userId);
                localAuth.setOpenid(openid);
                authDao.insertLocalAuth(localAuth);
                //添加了用户信息后，再添加一个用户存档记录
                UserArchive userArchive = new UserArchive();
                userArchive.setUserId(userId);
                userQuestionDao.insertUserArchive(userArchive);
            }
            //todo 这里考虑下要不要把用户存档保存在redis里
            return new TokenInfo(JwtUtils.createToken(localAuth.getUserId()), JwtUtils.expireIn);
        } catch (IOException e) {
            logger.error("获取openid失败", e);
            throw new LoginException();
        }
    }

    /**
     * 用js_code来获取openid
     *
     * @param jsCode
     * @return
     */
    private String jsCode2Openid(String jsCode) throws IOException {
        String url = "https://api.weixin.qq.com/sns/jscode2session";
        List<NameValuePair> params = new ArrayList<>(4);
        params.add(new BasicNameValuePair("js_code", jsCode));
        params.add(new BasicNameValuePair("appId", "wx7012b5c9a6fbf87a"));  //这里考虑换成常量
        params.add(new BasicNameValuePair("secret", "bdfd48870548a5e25fa654ee8a17a701"));  //这里考虑换成常量
        params.add(new BasicNameValuePair("grant_type", "authorization_code"));
        String responseBody = HttpClientUtils.get(url, params);
        return JsonCode.getValue(responseBody, "$.openid");
    }
}
